﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.Entity;
using System.Data.Entity.Core.Objects;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Tools.Model;

namespace Tools.DataAccess.Repository
{
    public class ContextBase : DbContext, IDbContext
    {

        protected ContextBase(string connectionString)
            : base(connectionString)
        {
            Initialize();
        }

        protected ContextBase(DbConnection connection)
            : base(connection, true)
        {
            Initialize();
        }

        protected ContextBase()
            : base()
        {
            Initialize();
        }

        protected virtual void Initialize()
        {
            //this.Configuration.LazyLoadingEnabled = false;
            //ContextOptions.ProxyCreationEnabled = false;
            //((IObjectContextAdapter)this).ObjectContext.ObjectMaterialized += ObjectContext_ObjectMaterialized;
        }

        //void ObjectContext_ObjectMaterialized(object sender, ObjectMaterializedEventArgs e)
        //{
        //    //var entity = e.Entity as IObjectWithState;
        //    //if (entity != null)
        //    //{
        //    //    entity.EntityState = State.Unchanged;
        //    //    entity.OriginalValues = BuildOriginalValues(this.Entry(entity).OriginalValues);
        //    //}
        //}
        //private static Dictionary<string, object> BuildOriginalValues(DbPropertyValues originalValues)
        //{
        //    var result = new Dictionary<string, object>();
        //    foreach (var propertyName in originalValues.PropertyNames)
        //    {
        //        var value = originalValues[propertyName];
        //        if (value is DbPropertyValues)
        //        {
        //            result[propertyName] = BuildOriginalValues((DbPropertyValues)value);
        //        }
        //        else
        //        {
        //            result[propertyName] = value;
        //        }
        //    }
        //    return result;
        //}

        public IDbSet<TEntity> GetSet<TEntity>() where TEntity : EntityBase
        {
            return this.Set<TEntity>();
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();

            base.OnModelCreating(modelBuilder);
        }

        public int Save()
        {
            return this.SaveChanges();
        }

        public void ExecuteSqlCommand(string sqlCommand, params object[] parameters)
        {
            this.Database.ExecuteSqlCommand(sqlCommand, parameters);
        }

    }
}
